package com.archermind.style.service;

import com.archermind.style.bean.*;
import com.archermind.style.pojo.*;
import com.feng.fengDUtil.BaseService;
import com.archermind.style.util.ByteUtil;
import com.archermind.style.util.Search;
import com.feng.fengDUtil.Page;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.archermind.style.pojo.ElementEnum.*;

@Service
@Transactional
public class RuleService extends BaseService {

    private static final Logger log = LoggerFactory.getLogger(RuleService.class);

    @Autowired
    private StyleTypeService styleTypeService;

    @Autowired
    private InstanceService instanceService;

    @Autowired
    private DictService dictService;

    @Autowired
    private OperationService opService;

    public Page query(Page page,Search search) {
        ArrayList params = new ArrayList();
        String sql = "select u.* from  rule_"+search.getElement().name().toLowerCase() +" u where instanceId = ? ";
        params.add(search.getInstanceId());
        if(search.getStyleTypeId()!=null){
            sql+=" and u.styleTypeId = ?";
            params.add(search.getStyleTypeId());
        }
        sql += " order by u.styleTypeId,cast(u.scale as DECIMAL) asc";
        findPageList(Map.class,sql,page,params.toArray());
        return page;
    }

    public void delRule(String ids, ElementEnum element) {
        String[] idArray = ids.split(",");
        sql("delete from rule_"+element.name()+" where id in ("+genePlaceHolders(idArray.length)+")").update(idArray);
    }

    public void processXMLDom(Element root,Integer instanceId) {
        for(ElementEnum element:ElementEnum.values()){
            if(element.getStyleTag()==null){
                continue;
            }
            Element node = root.element(element.getStyleTag());
            List<Element> styleList = node.elements("Style");
            for(Element styleDom:styleList){
                String styleTypeName = styleDom.attributeValue("name");
                if(styleTypeName.equals("b_roadx1")){
                    System.out.println();
                }
                StyleType styleType = styleTypeService.getStyleType(element,styleTypeName);
                if(styleType == null){
                    continue;
                }
                List<Element> ruleDoms = styleDom.elements("Rule");
                for(Element ruleDom:ruleDoms){
                    switch (element){
                        case text:
                            cacheRuleText(instanceId, styleType, ruleDom);
                            break;
                        case point:
                            saveRulePoint(instanceId, styleType, ruleDom);
                            break;
                        case line:
                            saveRuleLine(instanceId, styleType, ruleDom,styleTypeName);
                            break;
                        case polygon:
                            saveRulePolygon(instanceId, styleType, ruleDom);
                            break;
                        case building:
                            saveRuleBuilding(instanceId, styleType, ruleDom);
                            break;
                        case arrow:
                            saveRuleArrow(instanceId, styleType, ruleDom);
                            break;
                        case roadSign:
                            saveRuleRoadSign(instanceId, styleType, ruleDom);
                            break;

                    }
                }
            }
        }
    }


    private void saveRulePoint(Integer instanceId, StyleType styleType, Element ruleDom) {
        Integer styleTypeId = styleType.getId();
        Element symbolizer = ruleDom.element("PointSymbolizer");
        RulePoint rule = new RulePoint();
        rule.setInstanceId(instanceId);
        rule.setStyleTypeId(styleTypeId);
        Element scaleDom = ruleDom.element("Scale");
        String scale = scaleDom.getText();
        rule.setScale(scale);
        rule.setPoiType(ByteUtil.parseByte(trimText(symbolizer,"poi-type")));
        rule.setPointDensity(ByteUtil.parseInteger(trimText(symbolizer,"density")));
        rule.setAllowOverlap(ByteUtil.parseByte(trimText(symbolizer,"allow-overlap")));
        rule.setIconName(dictService.getIconPath(trimText(symbolizer,"icon-name")));
        styleType.setTagForModify(trimText(symbolizer,"tag-for-modify"));

        StyleType textType = styleTypeService.getStyleType(text,trimText(symbolizer,"text-name"));
        if(textType==null){
            super.insert(rule);
            return;
        }

        styleType.setTextTypeId(textType.getId());
        styleType.setTextTag(textType.getTextTag());

        Set<RuleText> textRules = getRuleTextByStyleTypeIdAndScale(textType.getId(),scale);
        for(RuleText text:textRules){
            rule.setScale(getJoinScale(scale,text.getScale()));

            rule.setFontName(text.getFontName());
            rule.setFontSize(text.getFontSize());
            rule.setFontColor(text.getFontColor());
            rule.setFontWeight(text.getFontWeight());
            rule.setFontStyle(text.getFontStyle());
            rule.setHalosize(text.getHalosize());
            rule.setBgsize(text.getBgsize());
            rule.setHalocolor(text.getHalocolor());
            rule.setDensity(text.getDensity());
            rule.setFillarc(text.getFillarc());
            super.insert(rule);
        }
    }

      private void saveRuleLine(Integer instanceId, StyleType styleType, Element ruleDom,String oriLineStyleName) {
          Integer styleTypeId = styleType.getId();
        Element symbolizer = ruleDom.element("LineSymbolizer");
        RuleLine rule = new RuleLine();
        rule.setInstanceId(instanceId);
        rule.setStyleTypeId(styleTypeId);
        Element scaleDom = ruleDom.element("Scale");
        String scale = scaleDom.getText();
        rule.setScale(scale);

        rule.setStroke(dictService.getColorId(line,instanceId,trimText(symbolizer,"stroke")));
        rule.setStrokeWidth(ByteUtil.parseFloat(trimText(symbolizer,"stroke-width")));
        rule.setStrokeSide(dictService.getColorId(line,instanceId,trimText(symbolizer,"stroke-side")));

          rule.setSideWidth(ByteUtil.parseFloat(trimText(symbolizer,"side-width")));
          rule.setLineCap(trimText(symbolizer,"line-cap"));
          rule.setLineJoin(trimText(symbolizer,"line-join"));
          rule.setLineLevel(ByteUtil.parseInteger(trimText(symbolizer,"line-level")));
          rule.setStrokeTexture(dictService.getIconPath(trimText(symbolizer,"stroke-texture")));
          rule.setSideTexture(dictService.getIconPath(trimText(symbolizer,"side-texture")));
          rule.setSideWallTexture(dictService.getIconPath(trimText(symbolizer,"side-wall-texture")));
          rule.setModelHeight(ByteUtil.parseInteger(trimText(symbolizer,"model-height")));
          rule.setDashLineName(dictService.getDashLineId(instanceId,trimText(symbolizer,"dash-line-name")));

          String tagForModify = trimText(symbolizer,"tag-for-modify");
          styleType.setTagForModify(tagForModify);

          String textNameRaw = trimText(symbolizer,"text-name");
          if(StringUtils.isEmpty(textNameRaw)){
              super.insert(rule);
              return;
          }
          List<String> textNameList = Arrays.asList(textNameRaw.split(","));
          for(int i=0;i<textNameList.size();i++){
              StyleType textType;
              if(i == 0){
                  textType = styleTypeService.getStyleType(text,textNameList.get(i));
                  if(textType!=null){
                          styleType.setTextTypeId(textType.getId());
                          styleType.setTextTag(textType.getTextTag());
                  }
              }else{
                  StyleType lineStyle =   styleTypeService.getOrInsertLineStyle(oriLineStyleName,textNameList.get(i));
                  rule.setStyleTypeId(lineStyle.getId());
                  lineStyle.setTagForModify(tagForModify);
                  textType = styleTypeService.getStyleType(text,textNameList.get(i));
                  if(textType!=null){
                      lineStyle.setTextTypeId(textType.getId());
                      lineStyle.setTextTag(textType.getTextTag());
                  }
              }
              if(textType==null){
                  super.insert(rule);
                  continue;
              }

              Set<RuleText> textRules = getRuleTextByStyleTypeIdAndScale(textType.getId(),scale);
              for(RuleText text:textRules){
                  rule.setScale(getJoinScale(scale,text.getScale()));

                  rule.setFontName(text.getFontName());
                  rule.setFontSize(text.getFontSize());
                  rule.setFontColor(text.getFontColor());
                  rule.setFontWeight(text.getFontWeight());
                  rule.setFontStyle(text.getFontStyle());
                  rule.setHalosize(text.getHalosize());
                  rule.setBgsize(text.getBgsize());
                  rule.setHalocolor(text.getHalocolor());
                  rule.setDensity(text.getDensity());
                  rule.setFillarc(text.getFillarc());
                  super.insert(rule);
              }
          }
    }

    private void saveRulePolygon(Integer instanceId, StyleType styleType, Element ruleDom) {
        Integer styleTypeId = styleType.getId();
        Element symbolizer = ruleDom.element("PolygonSymbolizer");
        RulePolygon rule = new RulePolygon();
        rule.setInstanceId(instanceId);
        rule.setStyleTypeId(styleTypeId);
        Element scaleDom = ruleDom.element("Scale");
        rule.setScale(scaleDom.getText());

        rule.setFill(dictService.getColorId(polygon,instanceId,trimText(symbolizer,"fill")));
        rule.setBorderColor(dictService.getColorId(polygon,instanceId,trimText(symbolizer,"border-color")));
        rule.setBorderWidth(ByteUtil.parseInteger(trimText(symbolizer,"border-width")));
        rule.setRegionTexture(dictService.getIconPath(trimText(symbolizer,"region-texture")));
        rule.setBorderTexture(dictService.getIconPath(trimText(symbolizer,"border-texture")));
        rule.setRegionType(trimText(symbolizer,"region-type"));

        styleType.setTagForModify(trimText(symbolizer,"tag-for-modify"));
        super.insert(rule);
    }

    private void saveRuleBuilding(Integer instanceId, StyleType styleType, Element ruleDom) {
        Integer styleTypeId = styleType.getId();
        Element symbolizer = ruleDom.element("BuildingSymbolizer");
        RuleBuilding rule = new RuleBuilding();
        rule.setInstanceId(instanceId);
        rule.setStyleTypeId(styleTypeId);
        Element scaleDom = ruleDom.element("Scale");
        rule.setScale(scaleDom.getText());

        rule.setRoofColor(dictService.getColorId(building,instanceId,trimText(symbolizer,"roof-color")));
        rule.setRootColor(dictService.getColorId(building,instanceId,trimText(symbolizer,"root-color")));
        rule.setWallColor(dictService.getColorId(building,instanceId,trimText(symbolizer,"wall-color")));
        rule.setWindowColor(dictService.getColorId(building,instanceId,trimText(symbolizer,"window-color")));
        rule.setRoofLineColor(dictService.getColorId(building,instanceId,trimText(symbolizer,"roof-line-color")));
        rule.setWallLineColor(dictService.getColorId(building,instanceId,trimText(symbolizer,"wall-line-color")));
        rule.setDiffuse(ByteUtil.parseFloat(trimText(symbolizer,"diffuse")));
        rule.setLightSource(trimText(symbolizer,"light-source"));
        rule.setRoofTexture(dictService.getIconPath(trimText(symbolizer,"roof-texture")));
        rule.setWallTexture(dictService.getIconPath(trimText(symbolizer,"wall-texture")));
        rule.setWindowRepeat(ByteUtil.parseByte(trimText(symbolizer,"window-repeat")));
        rule.setRoofLineColor2d(dictService.getColorId(building,instanceId,trimText(symbolizer,"roof-line-color-2d")));
        rule.setRoofColor2d(dictService.getColorId(building,instanceId,trimText(symbolizer,"roof-color-2d")));

        styleType.setTagForModify(trimText(symbolizer,"tag-for-modify"));
        super.insert(rule);
    }

    private void saveRuleArrow(Integer instanceId, StyleType styleType, Element ruleDom) {
        Integer styleTypeId = styleType.getId();
        Element symbolizer = ruleDom.element("ArrowSymbolizer");
        RuleArrow rule = new RuleArrow();
        rule.setInstanceId(instanceId);
        rule.setStyleTypeId(styleTypeId);
        Element scaleDom = ruleDom.element("Scale");
        rule.setScale(scaleDom.getText());

        rule.setTailAndHeadDist(ByteUtil.parseInteger(trimText(symbolizer,"TailAndHeadDist")));
        rule.setLabelDistance(ByteUtil.parseInteger(trimText(symbolizer,"LabelDistance")));
        rule.setColor(dictService.getColorId(arrow,instanceId,trimText(symbolizer,"color")));
        rule.setWidth(ByteUtil.parseFloat(trimText(symbolizer,"width")));
        rule.setLength(ByteUtil.parseInteger(trimText(symbolizer,"length")));
        rule.setTexture(dictService.getIconPath(trimText(symbolizer,"texture")));

        styleType.setTagForModify(trimText(symbolizer,"tag-for-modify"));

        super.insert(rule);
    }

    private void saveRuleRoadSign(Integer instanceId, StyleType styleType, Element ruleDom) {
        Integer styleTypeId = styleType.getId();
        Element symbolizer = ruleDom.element("RoadSignSymbolizer");
        RuleRoadSign rule = new RuleRoadSign();
        rule.setInstanceId(instanceId);
        rule.setStyleTypeId(styleTypeId);
        Element scaleDom = ruleDom.element("Scale");
        String scale = scaleDom.getText();
        rule.setScale(scale);

        rule.setIconname(dictService.getIconPath(trimText(symbolizer,"iconname")));
        rule.setStretchingLen(ByteUtil.parseInteger(trimText(symbolizer,"stretching-len")));
        styleType.setTagForModify(trimText(symbolizer,"tag-for-modify"));

        StyleType textType = styleTypeService.getStyleType(text,trimText(symbolizer,"textname"));
        if(textType==null){
            super.insert(rule);
            return;
        }

        styleType.setTextTypeId(textType.getId());
        styleType.setTextTag(textType.getTextTag());

        Set<RuleText> textRules = getRuleTextByStyleTypeIdAndScale(textType.getId(),scale);
        for(RuleText text:textRules){
            rule.setScale(getJoinScale(scale,text.getScale()));

            rule.setFontName(text.getFontName());
            rule.setFontSize(text.getFontSize());
            rule.setFontColor(text.getFontColor());
            rule.setFontWeight(text.getFontWeight());
            rule.setFontStyle(text.getFontStyle());
            rule.setHalosize(text.getHalosize());
            rule.setBgsize(text.getBgsize());
            rule.setHalocolor(text.getHalocolor());
            rule.setDensity(text.getDensity());
            rule.setFillarc(text.getFillarc());
            super.insert(rule);
        }
    }

    //导入样式时专用
    public static ThreadLocal<Map<Integer,Map<Integer,RuleText>>> textStyleMap = new ThreadLocal<Map<Integer,Map<Integer,RuleText>>>();

    /**
     * 缓存文本样式
     * @param instanceId
     * @param styleType
     * @param ruleDom
     */
    private void cacheRuleText(Integer instanceId, StyleType styleType, Element ruleDom) {
        Element symbolizer = ruleDom.element("TextSymbolizer");
        RuleText rule = new RuleText();
        rule.setInstanceId(instanceId);
        rule.setStyleTypeId(styleType.getId());
        Element scaleDom = ruleDom.element("Scale");
        rule.setScale(scaleDom.getText());

        TextTypeEnum textType = TextTypeEnum.valueOf(trimText(symbolizer,"texttype"));
        ElementEnum colorType = null;
        switch (textType){
            case PointTextSymbolizer:colorType = ElementEnum.point;break;
            case LineTextSymbolizer:colorType = ElementEnum.line;break;
            case LableIconSymbolizer:colorType = ElementEnum.roadSign;break;
        }

        rule.setFontName(dictService.getFontId(instanceId,trimText(symbolizer,"font-name")));
        rule.setFontSize(dictService.getFontSizeId(instanceId,trimText(symbolizer,"font-size")));
        rule.setFontColor(dictService.getColorId(colorType,instanceId,trimText(symbolizer,"font-color")));
        rule.setFontWeight(trimText(symbolizer,"font-weight"));
        rule.setFontStyle(trimText(symbolizer,"font-style"));
        rule.setHalosize(ByteUtil.parseInteger(trimText(symbolizer,"halosize")));
        rule.setBgsize(ByteUtil.parseInteger(trimText(symbolizer,"bgsize")));
        rule.setHalocolor(dictService.getColorId(colorType,instanceId,trimText(symbolizer,"halocolor")));
        rule.setDensity(ByteUtil.parseInteger(trimText(symbolizer,"density")));
        rule.setFillarc(ByteUtil.parseFloat(trimText(symbolizer,"fillarc")));

        styleType.setTextTag(trimText(symbolizer,"tag-for-modify"));

        Map<Integer,RuleText> ruleTextMap = textStyleMap.get().get(styleType.getId());
        if(ruleTextMap == null){
            ruleTextMap = new HashMap<>();
            textStyleMap.get().put(styleType.getId(),ruleTextMap);
        }
        String[] scaleArray = rule.getScale().split(",");
        Integer from = Integer.parseInt(scaleArray[0]);
        Integer to = Integer.parseInt(scaleArray[1]);
        for(int i=from;i<=to;i++){
            ruleTextMap.put(i,rule);
        }
    }

    private Set<RuleText> getRuleTextByStyleTypeIdAndScale(Integer styleTypeId, String scale){
        Set<RuleText> ret = new HashSet<>();
        String[] scaleArray = scale.split(",");
        Integer from = Integer.parseInt(scaleArray[0]);
        Integer to = Integer.parseInt(scaleArray[1]);
        for(int i=from;i<=to;i++){
            RuleText x = textStyleMap.get().get(styleTypeId).get(i);
            if(x!=null){
                ret.add(x);
            }
        }
        return ret;
    }
    private String getJoinScale(String scale,String scaleText){
        Integer[] retScale = new Integer[2];
        String[] scaleArray= scale.split(",");
        String[] scaleTextArray= scaleText.split(",");
        Integer from = Integer.parseInt(scaleArray[0]);
        Integer to = Integer.parseInt(scaleArray[1]);
        Integer fromText = Integer.parseInt(scaleTextArray[0]);
        Integer toText = Integer.parseInt(scaleTextArray[1]);

        retScale[0] = from>= fromText?from:fromText;
        retScale[1] = to>= toText?toText:to;
        return StringUtils.join(retScale,",");
    }

    public void combine(CombineBean combineBean) {
        String table = "rule_"+combineBean.getElement().name().toLowerCase();
        List<Integer> params = new ArrayList<>();
        params.add(combineBean.getInstanceId());
        params.add(combineBean.getStyleTypeId());
        for(CombineSon rule:combineBean.getRules()){
            params.add(rule.getRuleId());
        }

        String sql = "delete u from "+table+" u where instanceId = ? and styleTypeId = ? and id not in ("+genePlaceHolders(params.size()-2)+")";
        sql(sql).update(params.toArray());

        List<CombineSon> updateList = new ArrayList<>();
        List<CombineSon> insertList = new ArrayList<>();

        for(CombineSon rule:combineBean.getRules()){
            if(existsInList(rule,updateList)){
                insertList.add(rule);
            }else{
                updateList.add(rule);
            }
        }
        String updateSql = "update "+table+ " u set u.scale = ? where id = ?";
        for(CombineSon rule:updateList){
            sql(updateSql).update(new Object[]{ rule.getFrom()+","+rule.getTo(),rule.getRuleId() });
        }

        for(CombineSon rule:insertList){
            switch (combineBean.getElement()){
                case point:
                    RulePoint rulePoint = selectById(RulePoint.class,rule.getRuleId());
                    rulePoint.setId(null);
                    rulePoint.setScale(rule.getFrom()+","+rule.getTo());
                    insert(rulePoint);
                    break;
                case line:
                    RuleLine ruleLine = selectById(RuleLine.class,rule.getRuleId());
                    ruleLine.setId(null);
                    ruleLine.setScale(rule.getFrom()+","+rule.getTo());
                    insert(ruleLine);
                    break;
                case text:
                    RuleText ruleText = selectById(RuleText.class,rule.getRuleId());
                    ruleText.setId(null);
                    ruleText.setScale(rule.getFrom()+","+rule.getTo());
                    insert(ruleText);
                    break;
                case polygon:
                    RulePolygon rulePolygon = selectById(RulePolygon.class,rule.getRuleId());
                    rulePolygon.setId(null);
                    rulePolygon.setScale(rule.getFrom()+","+rule.getTo());
                    insert(rulePolygon);
                    break;
                case building:
                    RuleBuilding ruleBuilding = selectById(RuleBuilding.class,rule.getRuleId());
                    ruleBuilding.setId(null);
                    ruleBuilding.setScale(rule.getFrom()+","+rule.getTo());
                    insert(ruleBuilding);
                    break;
                case arrow:
                    RuleArrow ruleArrow = selectById(RuleArrow.class,rule.getRuleId());
                    ruleArrow.setId(null);
                    ruleArrow.setScale(rule.getFrom()+","+rule.getTo());
                    insert(ruleArrow);
                    break;
                case roadSign:
                    RuleRoadSign roadSign = selectById(RuleRoadSign.class,rule.getRuleId());
                    roadSign.setId(null);
                    roadSign.setScale(rule.getFrom()+","+rule.getTo());
                    insert(roadSign);
                    break;
            }
        }
    }

    private boolean existsInList(CombineSon son,List<CombineSon> updateList ) {
        for(CombineSon rule:updateList){
            if(rule.getRuleId().equals(son.getRuleId())){
                return true;
            }
        }
        return false;
    }

    /**
     * 批量修改样式
     * @param groupEditBean
     */
    public void groupEdit(GroupEditBean groupEditBean) {
        String table = "rule_"+groupEditBean.getElement().name().toLowerCase();
        ArrayList params = new ArrayList();
        params.add(groupEditBean.getFieldVal());

        String sql = "update "+table+" u set u."+groupEditBean.getField()+" = ? where id in ("+genePlaceHolders(groupEditBean.getRuleIds().size())+")";
        params.addAll(groupEditBean.getRuleIds());
        sql(sql).update(params.toArray());
    }

    public void delRules(Integer instanceId,ElementEnum element,Integer styleId){
        sql("delete from rule_"+element.name()+" where instanceId = ? and styleTypeId = ? ").update(new Integer[]{instanceId,styleId});
    }
    public void copyStyle(Integer instanceId, Integer styleId, ElementEnum element, Integer[] ruleIds) {

            List<DictColor> colors = dictService.usedDictColor(element,ruleIds);
            List<DictFont> fonts = dictService.usedFont(element,ruleIds);
            List<DictFontSize> fontSizes = dictService.usedFontSize(element,ruleIds);
            List<DictDashLine> dashLines = dictService.usedDashLine(element,ruleIds);


            List<RulePoint> points = null;
            List<RuleLine> lines = null;
            List<RulePolygon> polygons = null;
            List<RuleBuilding> buildings = null;
            List<RuleArrow> arrows = null;
            List<RuleRoadSign> ruleRoadSigns = null;

            String placeHolders = genePlaceHolders(ruleIds.length);
            switch (element){
                case point:
                     points = sql("select * from rule_point where id in ("+placeHolders+")").list(RulePoint.class,ruleIds);
                    for(RulePoint item:points){
                        item.setDictFontName(dictService.getDictFont(item.getFontName(),fonts));
                        item.setDictFontSize(dictService.getDictFontSize(item.getFontSize(),fontSizes));
                        item.setDictFontColor(dictService.getDictColor(item.getFontColor(),colors));
                        item.setDictHalocolor(dictService.getDictColor(item.getHalocolor(),colors));
                    }
                    break;
                case line:
                     lines = sql("select * from rule_line where id in ("+placeHolders+")").list(RuleLine.class,ruleIds);
                    for(RuleLine item:lines){
                        item.setDictDashLineName(dictService.getDictDashLine(item.getDashLineName(),dashLines));
                        item.setDictStroke(dictService.getDictColor(item.getStroke(),colors));
                        item.setDictStrokeSide(dictService.getDictColor(item.getStrokeSide(),colors));
                        item.setDictFontName(dictService.getDictFont(item.getFontName(),fonts));
                        item.setDictFontSize(dictService.getDictFontSize(item.getFontSize(),fontSizes));
                        item.setDictFontColor(dictService.getDictColor(item.getFontColor(),colors));
                        item.setDictHalocolor(dictService.getDictColor(item.getHalocolor(),colors));
                    }
                    break;
                case polygon:
                     polygons = sql("select * from rule_polygon where id in ("+placeHolders+")").list(RulePolygon.class,ruleIds);
                    for(RulePolygon item:polygons){
                        item.setDictBorderColor(dictService.getDictColor(item.getBorderColor(),colors));
                        item.setDictFill(dictService.getDictColor(item.getFill(),colors));
                    }
                    break;
                case building:
                    buildings = sql("select * from rule_building where id in ("+placeHolders+")").list(RuleBuilding.class,ruleIds);
                    for(RuleBuilding item:buildings){
                        item.setDictRoofColor(dictService.getDictColor(item.getRoofColor(),colors));
                        item.setDictRootColor(dictService.getDictColor(item.getRootColor(),colors));
                        item.setDictWallColor(dictService.getDictColor(item.getWallColor(),colors));
                        item.setDictWindowColor(dictService.getDictColor(item.getWindowColor(),colors));
                        item.setDictRoofLineColor(dictService.getDictColor(item.getRoofLineColor(),colors));
                        item.setDictWallLineColor(dictService.getDictColor(item.getWallLineColor(),colors));
                        item.setDictRoofLineColor2d(dictService.getDictColor(item.getRoofLineColor2d(),colors));
                        item.setDictRoofColor2d(dictService.getDictColor(item.getRoofColor2d(),colors));
                    }
                    break;
                case arrow:
                     arrows  = sql("select * from rule_arrow where id in ("+placeHolders+")").list(RuleArrow.class,ruleIds);
                    for(RuleArrow item:arrows){
                        item.setDictColor(dictService.getDictColor(item.getColor(),colors));
                    }
                    break;
                case roadSign:
                    ruleRoadSigns  = sql("select * from rule_roadSign where id in ("+placeHolders+")").list(RuleRoadSign.class,ruleIds);
                    for(RuleRoadSign item:ruleRoadSigns){
                        item.setDictFontName(dictService.getDictFont(item.getFontName(),fonts));
                        item.setDictFontSize(dictService.getDictFontSize(item.getFontSize(),fontSizes));
                        item.setDictFontColor(dictService.getDictColor(item.getFontColor(),colors));
                        item.setDictHalocolor(dictService.getDictColor(item.getHalocolor(),colors));
                    }
                    break;
            }

            //查找在目标intance 中有没有一样的样式函数，如果没有，样式函数才也copy过去

            dictService.mergeColor(colors,element,instanceId);
            dictService.mergeFont(fonts,instanceId);
            dictService.mergeFontSize(fontSizes,instanceId);
            dictService.mergeDashLine(dashLines,instanceId);

            for(DictColor dict:colors){
                if(dict.getId()==null){
                    insert(dict);
                }
            }
            for(DictFont dict:fonts){
                if(dict.getId()==null){
                    insert(dict);
                }
            }
            for(DictFontSize dict:fontSizes){
                if(dict.getId()==null){
                    insert(dict);
                }
          }
            for(DictDashLine dict:dashLines){
                if(dict.getId()==null){
                    insert(dict);
                }
            }

         switch (element){
            case point:
                //更新dictId
                for(RulePoint item:points){
                    item.setFontName(dictService.getDictFontId(item.getDictFontName()));
                    item.setFontSize(dictService.getDictFontSizeId(item.getDictFontSize()));
                    item.setFontColor(dictService.getDictColorId(item.getDictFontColor()));
                    item.setHalocolor(dictService.getDictColorId(item.getDictHalocolor()));
                    item.setStyleTypeId(styleId);
                    item.setInstanceId(instanceId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case line:
                for(RuleLine item:lines){
                    item.setDashLineName(dictService.getDictDashLineId(item.getDictDashLineName()));
                    item.setStroke(dictService.getDictColorId(item.getDictStroke()));
                    item.setStrokeSide(dictService.getDictColorId(item.getDictStrokeSide()));
                    item.setFontName(dictService.getDictFontId(item.getDictFontName()));
                    item.setFontSize(dictService.getDictFontSizeId(item.getDictFontSize()));
                    item.setFontColor(dictService.getDictColorId(item.getDictFontColor()));
                    item.setHalocolor(dictService.getDictColorId(item.getDictHalocolor()));
                    item.setStyleTypeId(styleId);
                    item.setInstanceId(instanceId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case polygon:
                for(RulePolygon item:polygons){
                    item.setBorderColor(dictService.getDictColorId(item.getDictBorderColor()));
                    item.setFill(dictService.getDictColorId(item.getDictFill()));
                    item.setStyleTypeId(styleId);
                    item.setInstanceId(instanceId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case building:
                for(RuleBuilding item:buildings){
                    item.setRoofColor(dictService.getDictColorId(item.getDictRoofColor()));
                    item.setRootColor(dictService.getDictColorId(item.getDictRootColor()));
                    item.setWallColor(dictService.getDictColorId(item.getDictWallColor()));
                    item.setWindowColor(dictService.getDictColorId(item.getDictWindowColor()));
                    item.setRoofLineColor(dictService.getDictColorId(item.getDictRoofLineColor()));
                    item.setWallLineColor(dictService.getDictColorId(item.getDictWallLineColor()));
                    item.setRoofLineColor2d(dictService.getDictColorId(item.getDictRoofLineColor2d()));
                    item.setRoofColor2d(dictService.getDictColorId(item.getDictRoofColor2d()));
                    item.setStyleTypeId(styleId);
                    item.setInstanceId(instanceId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case arrow:
                for(RuleArrow item:arrows){
                    item.setColor(dictService.getDictColorId(item.getDictColor()));
                    item.setStyleTypeId(styleId);
                    item.setInstanceId(instanceId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case roadSign:
                for(RuleRoadSign item:ruleRoadSigns){
                    item.setFontName(dictService.getDictFontId(item.getDictFontName()));
                    item.setFontSize(dictService.getDictFontSizeId(item.getDictFontSize()));
                    item.setFontColor(dictService.getDictColorId(item.getDictFontColor()));
                    item.setHalocolor(dictService.getDictColorId(item.getDictHalocolor()));
                    item.setStyleTypeId(styleId);
                    item.setInstanceId(instanceId);
                    item.setId(null);
                    insert(item);
                }
                break;
        }
    }

    public void copyStyle(Integer styleId, ElementEnum element, Integer[] ruleIds) {

        List<RulePoint> points = null;
        List<RuleLine> lines = null;
        List<RulePolygon> polygons = null;
        List<RuleBuilding> buildings = null;
        List<RuleArrow> arrows = null;
        List<RuleRoadSign> ruleRoadSigns = null;
        String placeHolders = genePlaceHolders(ruleIds.length);
        switch (element){
            case point:
                points = sql("select * from rule_point where id in ("+placeHolders+")").list(RulePoint.class,ruleIds);
                for(RulePoint item:points){
                    item.setStyleTypeId(styleId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case line:
                lines = sql("select * from rule_line where id in ("+placeHolders+")").list(RuleLine.class,ruleIds);
                for(RuleLine item:lines){
                    item.setStyleTypeId(styleId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case polygon:
                polygons = sql("select * from rule_polygon where id in ("+placeHolders+")").list(RulePolygon.class,ruleIds);
                for(RulePolygon item:polygons){
                    item.setStyleTypeId(styleId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case building:
                buildings = sql("select * from rule_building where id in ("+placeHolders+")").list(RuleBuilding.class,ruleIds);
                for(RuleBuilding item:buildings){
                    item.setStyleTypeId(styleId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case arrow:
                arrows  = sql("select * from rule_arrow where id in ("+placeHolders+")").list(RuleArrow.class,ruleIds);
                for(RuleArrow item:arrows){
                    item.setStyleTypeId(styleId);
                    item.setId(null);
                    insert(item);
                }
                break;
            case roadSign:
                ruleRoadSigns  = sql("select * from rule_roadSign where id in ("+placeHolders+")").list(RuleRoadSign.class,ruleIds);
                for(RuleRoadSign item:ruleRoadSigns){
                    item.setStyleTypeId(styleId);
                    item.setId(null);
                    insert(item);
                }
                break;
        }
    }

    private String trimText(Element element,String tag){
        String text = element.attributeValue(tag);
        if(text!=null){
            return text.trim();
        }
        return null;
    }

    public StyleType saveRulePoint(RulePoint rulePoint) throws Exception{
        StyleType textStyleType = null;
        RuleText text = new RuleText();
        dictService.bcPoint.copy(rulePoint,text,null);
        int textStatus = text.testField();
        if(textStatus==1){
            //如果包含文本样式，
            textStyleType = styleTypeService.checkAndSaveTextType(text);
        }else if(textStatus==-1){
            throw new Exception("请检查文本样式的字段，确保所有字段非空！");
        }
        saveOrUpdate(rulePoint);
        return textStyleType;
    }

    public StyleType saveRuleLine(RuleLine ruleLine) throws Exception{
        StyleType textStyleType = null;
        RuleText text = new RuleText();
        dictService.bcLine.copy(ruleLine,text,null);
        int textStatus = text.testField();
        if(textStatus==1){
            //如果包含文本样式，
            textStyleType = styleTypeService.checkAndSaveTextType(text);
        }else if(textStatus==-1){
            throw new Exception("请检查文本样式的字段，确保所有字段非空！");
        }
        saveOrUpdate(ruleLine);
        return textStyleType;
    }

    public StyleType saveRuleRoadSign(RuleRoadSign ruleRoadSign) throws Exception{
        StyleType textStyleType = null;
        RuleText text = new RuleText();
        dictService.bcRoadSign.copy(ruleRoadSign,text,null);
        int textStatus = text.testField();
        if(textStatus==1){
            //如果包含文本样式，
            textStyleType = styleTypeService.checkAndSaveTextType(text);
        }else if(textStatus==-1){
            throw new Exception("请检查文本样式的字段，确保所有字段非空！");
        }
        saveOrUpdate(ruleRoadSign);
        return textStyleType;
    }


    public void copyStyle( Integer instanceId,  Integer styleId, ElementEnum element,Integer oldInstanceId,  Integer[] ruleIds) throws Exception {
        String comment ="复制了部分样式。从"+instanceService.getInstanceName(oldInstanceId)+"至"+instanceService.getInstanceName(instanceId);
        opService.saveLog(comment,instanceId);
        delRules(instanceId,element,styleId);
        if(instanceId.equals(oldInstanceId)){
            copyStyle(styleId,element,ruleIds);
        }else{
            copyStyle(instanceId,styleId,element,ruleIds);
        }
    }
}
